<?php

namespace App\Utils;

use App\Constants\CodeData;
use App\Dao\UserDao;
use App\Dao\UserGagDao;
use App\Exception\MessageException;
use App\Model\User;
use App\Model\UserChatLimit;
use App\Services\JwtService;
use App\Services\YunXinCloud\WyyClientService;
use Hyperf\Context\ApplicationContext;
use Hyperf\HttpServer\Contract\RequestInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use function Hyperf\Translation\trans;

class FunUtil
{
    public static function socket_client($event = '', $uid = '', $session_id = '', $data = '')
    {
        switch ($event) {
            case "login":
            case "logout":
            case "send":
            case "send_message":
            case "new_user_reject":
            case "notice":
            case "chat_hosting":
            case "update_session":
            case "real_send":
            case "assistant":
            case "assistant_uid":
            case "pay_success":
            case "anchor_task":
            case "ping":
            case "goddess_rank":
                (new WyyClientService())->fastPush(compact("event", "uid", "session_id", "data"));
                break;
            default:
                $result['event'] = $event;
                $result['uid'] = $uid;
                $result['session_id'] = $session_id;
                $result['data'] = $data;
                $client = stream_socket_client('tcp://apitest.iyliao.com:8282');
                if (!$client) {
                    LoggerUtil::write("socket", 'tcp://apitest.iyliao.com', "error_connect");
                } else {
                    // 模拟超级用户，以文本协议发送数据，注意Text文本协议末尾有换行符（发送的数据中最好有能识别超级用户的字段），这样在Event.php中的onMessage方法中便能收到这个数据，然后做相应的处理即可
                    fwrite($client, json_encode($result, true) . "\n");
                }
        }
    }

    /**
     * Note - 登录省份黑名单
     * DateTime 2024/7/10 12:06
     * User Admin
     * @param $province
     * @param $uid
     * @return bool
     */
    public static function checkBlockLoginProvince($province, $uid = '')
    {
        if (empty($province)) {
            return false;
        }
        $block_provinces = ["福建"];
        if (in_array($province, $block_provinces)) {
            LoggerUtil::write("block_login_city", "$uid--$province");
            return true;
        }
        return false;
    }

    public static function formatHeadImg($head_image)
    {
        if (empty($head_image)) return '';
        if (!stristr($head_image, "http://") && !stristr($head_image, "https://")) {
            $resImg = IMAGE_UPLOAD . $head_image . "?" . IMAGE_VERSION;
        } else {
            $resImg = $head_image;
        }
        return $resImg;
        // 压缩头像
        // return AliyunOssHelper::compressImageHandle($resImg, 500);
    }

    /**
     * 格式相片url
     * @param $photo
     * @return string
     */
    public static function formatPhoto($photo)
    {
        if (empty($photo)) return $photo;
        if (!stristr($photo, "http://") && !stristr($photo, "https://")) {
            return IMAGE_UPLOAD . $photo . "?" . IMAGE_VERSION;
        } else {
            return $photo;
        }
    }

    /**
     * Note - 获取IP
     * DateTime 2024/7/10 12:06
     * User Admin
     * @return string
     */
    public static function getClientIp(): string
    {
        try {
            $request = ApplicationContext::getContainer()->get(RequestInterface::class);
            $headers = $request->getHeaders();
            if (!empty($headers['x-forwarded-for'][0])) {
                return $headers['x-forwarded-for'][0];
            } elseif (!empty($headers['x-real-ip'][0])) {
                return $headers['x-real-ip'][0];
            }
            $serverParams = $request->getServerParams();
            return $serverParams['remote_addr'] ?? '127.0.0.1';
        } catch (\Throwable $e) {
            LoggerUtil::write("getClientIp", $e->getMessage());
            return '172.21.0.1';
        }

        /**
         * nginx 配置
         * location / {
         * # proxy host and ip information
         * proxy_set_header Host $http_host;
         * proxy_set_header X-Real-IP $remote_addr;
         * proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         *
         * # proxy
         * proxy_pass http://127.0.0.1:9501;
         * }
         **/
    }

    /**
     * Note - 根据出生日期获取年龄
     * DateTime 2024/7/10 12:06
     * User Admin
     * @param $birthday
     * @return int|string
     */
    public static function birthday($birthday)
    {
        list($year, $month, $day) = explode("-", $birthday);
        $year_diff = date("Y") - $year;
        $month_diff = date("m") - $month;
        $day_diff = date("d") - $day;
        if ($day_diff < 0 || $month_diff < 0)
            $year_diff--;
        return $year_diff;
    }

    /**
     * Note -根据出生日期获取星座
     * DateTime 2024/7/10 12:07
     * User Admin
     * @param $birthday
     * @return false|mixed
     */
    public static function constellation($birthday)
    {
        list($year, $month, $day) = explode("-", $birthday);
        // 检查参数有效性
        if ($month < 1 || $month > 12 || $day < 1 || $day > 31) {
            return (false);
        }
        // 星座名称以及开始日期
        $signs = array(
            array("20" => "水瓶座"),
            array("19" => "双鱼座"),
            array("21" => "白羊座"),
            array("20" => "金牛座"),
            array("21" => "双子座"),
            array("22" => "巨蟹座"),
            array("23" => "狮子座"),
            array("23" => "处女座"),
            array("23" => "天秤座"),
            array("24" => "天蝎座"),
            array("22" => "射手座"),
            array("22" => "摩羯座")
        );
        $sign_start = key($signs[(int)$month - 1]);
        $sign_name = current($signs[(int)$month - 1]);
        if ($day < $sign_start) {
            $month = ($month - 2 < 0) ? 11 : $month - 2;
            $sign_start = key($signs[$month]);
            $sign_name = current($signs[$month]);

        }
        return $sign_name;
    }

    /**
     * 验证用户uid 和session_id 信息
     * @param $uid
     * @param $session_id
     * @param string $language
     * @param bool $teen_mode
     * @return mixed
     */
    public static function checkUser($uid, $session_id, $language = 'zh-cn', $teen_mode = true)
    {
        if (empty($uid) || empty($session_id)) {
            throw new MessageException('缺少登录参数', CodeData::NEED_TIPS, ['result' => 2]);
        }

        $payload = JwtService::verifyToken($session_id);
        if (!$payload || $payload['uid'] != $uid) {
            throw new MessageException('登录过期', CodeData::NEED_TIPS, ['result' => 2]);
        }

        $userInfo = (new UserDao())->findUserInfoCache($uid, $language);
        LoggerUtil::write('check_user', json_encode($userInfo));

        if (!empty($userInfo) && $userInfo['session_id'] === $session_id) {
            if ($userInfo['status'] != 0) {
                throw new MessageException('用户已被封禁！', CodeData::NEED_TIPS, ['result' => 2]);
            }
            if ($userInfo['status'] == 1) {
                throw new MessageException('该账户已注销！', CodeData::NEED_TIPS, ['result' => 4]);
            }

            if (($userInfo['sex'] == 2) && (FunUtil::checkBlockLoginProvince($userInfo['province'], $userInfo['id']))) {
                throw new MessageException('网络繁忙，请稍后再试');
            }

            // // 是否开启青少年模式
            // if ($teen_mode) {
            //     $teen_mode = $userModel->find('*', 'uid = ? and status=1', [$uid], '', 'tb_teen_mode');
            //     $userInfo['teen_mode'] = empty($teen_mode) ? 0 : 1;
            //     if ($userInfo['teen_mode'] == 1) {
            //         Tool::JSON(200, array('result' => 20, 'msg' => $userInfo), '青少年模式已开启');
            //     }
            // }

            // 判断用户是离线状态 调用接口更新状态
            $update = ['click_time' => time()];
            if ($userInfo['online'] == 0) {
                $online = (new WyyClientService())->queryUserEvents($uid);
                $update['online'] = $online;
            }
            User::query()->where('id', $uid)->update($update);
            return $userInfo;
        } else {
            throw new MessageException('登录信息有误', CodeData::NEED_TIPS, ['result' => 2]);
        }
    }

    /**
     * Note - 判断uid和IMEI用户是否被禁言
     * DateTime 2024/7/18 18:02
     * User Admin
     * @param $uid
     * @param $imei
     * @return bool
     */
    public static function gagUserChat($uid = 0, $imei = '')
    {
        $return = false;
        $userGagAction = UserGagDao::getInstance();
        if (empty($uid) && $userGagAction->checkUidGag($uid, 1)) {
            $return = true;
        }
        if (empty($imei) && $userGagAction->checkGag($imei, 2)) {
            $return = true;
        }
        return $return;
    }


    /**
     * Note - 用户聊天限制表,前提是请亲密度关系为0
     * DateTime 2024/7/29 14:29
     * User Admin
     * @param mixed $uid
     * @param mixed $user_id
     * @param int $closeness
     * @return int
     */
    public static function chatLimit(mixed $uid, mixed $user_id, int $closeness)
    {
        $limits = UserChatLimit::query()->where('uid', $uid)->where('status', 1)->first();
        $limits = modelToArray($limits);
        $is_limit = 0;
        if (!empty($limits)) {
            if ($limits['type'] == 1 && !$closeness) {
                if (
                    empty($limits['chat_uids']) || !in_array($user_id, explode(',', $limits['chat_uids']))
                ) {
                    $is_limit = 1;
                }
            }

            if (
                $limits['type'] == 2 &&
                (
                    (!empty($limits['user_ids']) && in_array($user_id, explode(',', $limits['user_ids'])))
                    || (!$closeness && (empty($limits['chat_uids']) || !in_array($user_id, explode(',', $limits['chat_uids']))))
                )
            ) {
                $is_limit = 1;
            }

        }
        return $is_limit;
    }


    /**
     * 短信召回赠送金币操作
     *
     * 这个方法需要再用户登录更新登录时间前操作，因为要获取用户最后登录时间
     *
     * @param string $user_id
     * @param int $new_login_time 这个值可以使用 time() 但是为了数据的一致性，由外部新的登录时间传进来
     * @return bool|int
     */
    public static function smsRecall($user_id, $phone, $new_login_time)
    {
        // $smsRecallLogModel = new SmsRecallLogModel();
        // // 查找用户的召回记录
        // $sms_recall_log = $smsRecallLogModel->find('id,setting_id,is_send_gold,is_recall,send_gold', 'phone = ?', [$phone], 'id desc');
        // // 判断用户是否需要赠送短信召回金币 // 最后一条召回记录没有回归，没有发送过金币
        // if (!empty($sms_recall_log) && $sms_recall_log['is_recall'] == 0 && $sms_recall_log['is_send_gold'] == 0) {
        //     // 更新召回记录
        //     $smsRecallLogModel->update($sms_recall_log['id'], ['user_id' => $user_id, 'is_recall' => $new_login_time]);
        //     // 添加召回用户信息
        //     (new SmsRecallBackUserModel())->insert(['user_id' => $user_id, 'create_time' => $new_login_time, 'last_login_time' => $new_login_time, 'log_id' => $sms_recall_log['id']]);
        //
        // }
    }


    // 清理客户端数据
    public static function getCleanConfig()
    {
        $clean_status = 0; // 0表示正常运营状态，1表示清理状态
        $clean_ver = 0; // 每次要清理时，就要+1，并保证clean_status为1

        /*$from = intval($_REQUEST['from']);
        $channel = trim($_REQUEST['channel']);
        $version_code = intval($_REQUEST['version_code']);
        if($from == 1){
            //安卓
            if($version_code == 22){
                $clean_status = 0;
                $clean_ver = 4;
            }
        }else{
            //IOS
            if($version_code == 19){
                $clean_status = 0;
                $clean_ver = 6;
            }

        }*/
        /*if(in_array($channel, array('l200001','l200002'))){
                $clean_status = 1;
                $clean_ver = 7;
        }*/
        return array('clean_status' => $clean_status, 'clean_ver' => $clean_ver);
    }


    /**
     *
     * Note - 计算帖子发布时间
     * DateTime 2024/7/29 14:29
     * User Admin
     * @param $publish_time
     * @param $language
     * @return array|string
     */
    public static function TopicPushTimeAgo($publish_time, $language = 'en')
    {
        $t = (time() - (int)$publish_time);
        if ($t < 3600) {
            $t1 = ceil($t / 60);
            $time_content = trans("message.分钟前", ['t' => $t1], $language);
        } elseif ($t < 24 * 3600) {
            $t2 = ceil($t / 3600);
            $time_content = trans("message.小时前", ['t' => $t2], $language);
        } elseif ($t < 7 * 24 * 3600) {
            $t3 = ceil($t / 24 / 3600);
            $time_content = trans("message.天前", ['t' => $t3], $language);
        } elseif ($t < 21 * 24 * 3600) {
            $t4 = ceil($t / 7 / 24 / 3600);
            $time_content = trans("message.周前", ['t' => $t4], $language);
        } elseif ($t < 30 * 24 * 3600) {
            $t5 = ceil($t / 30 / 24 / 3600);
            $time_content = trans("message.个月前", ['t' => $t5], $language);
        } else {
            $time_content = trans("message.年前", ['t' => 1], $language);
        }
        return $time_content;
    }

    /**
     * 获取唯一订单
     * @return string
     */
    public static function formatUniqidOrderId($num)
    {
        return date('YmdHis') . sprintf('%06d', self::uniqidOrderId($num)) . sprintf('%02d', rand(0, 99));
    }

    /**
     * 唯一订单id
     * @param $num
     * @return string
     */
    public static function uniqidOrderId($num)
    {
        // 假设已经建立了Redis连接并存储在$redis变量中
        $redisKey = 'order_id_increment';
        $redis = RedisClient::getInstance();
        // 获取当前ID
        $id = $redis->get($redisKey);
        if ($id == null || $id > 99999) {
            $id = 1;
        } else {
            $id++;
        }
        // 设置新的ID到Redis
        $redis->set($redisKey, $id);
        return $num . sprintf('%05d', $id);
    }


}